﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Calculated Properties Tests</title>
		
		<link href="../Common/Styles/qunit.css" type="text/css" rel="stylesheet" />
		
		<script src="../Common/Scripts/JQuery/jquery-1.3.2.js" type="text/javascript"></script>
		<script src="../Common/Scripts/QUnit/qunit.js" type="text/javascript"></script>
		<script src="../Common/Scripts/Microsoft/MicrosoftAjax.js" type="text/javascript"></script>
		<script src="../Common/Scripts/ExoWeb/exoweb.js" type="text/javascript"></script>
		<script src="../Common/Scripts/QUnit/qunit.ext.js" type="text/javascript"></script>
		<script src="../Common/Scripts/ExoWeb/exoweb.model.js" type="text/javascript"></script>
		<script src="../Common/Scripts/ExoWeb/exoweb.mapper.js" type="text/javascript"></script>
		<script src="../Common/Scripts/ExoWeb/exoweb.mock.js" type="text/javascript"></script>
		<script src="../Common/Scripts/mock-driver.js" type="text/javascript"></script>
		
		<script type="text/javascript">
			var context = ExoWeb.context({ model: { driver: { id: "1", from: "Driver" } } });
			
			function getAllowedSalesPersons() {
				return $transform(Employee.meta.known()).where(function(obj) {return obj.get_HireDate() <= this.get_DateCreated();}, this);
			}
			
			setupTest("list-property", { description: "list property", expect: 5 }, function() {
				//Driver.$AllowedSalesPersons.init(context.model.driver, []);
				var list = context.model.driver.get_AllowedSalesPersons();
				
				// watch for changes
				var listChanged = false;
				Sys.Observer.addCollectionChanged(list, function() { listChanged = true; });

				ok(context.model.driver.get_AllowedSalesPersons() === list, "setting up a calculated property should not cause a new list to be created so observers will still work");
				same(getAllowedSalesPersons.apply(context.model.driver), list, "calculated property should have the correct values in it");

				var curDate = context.model.driver.get_DateCreated();

				// cause the list to recalculate but have NO changes
				listChanged = false;
				context.model.driver.set_DateCreated(new Date(curDate.getFullYear(), curDate.getMonth(), curDate.getDate() + 1));
				ok(!listChanged, "if the calculated list has no changes, don't raise a collecton changed event");

				// cause the list to recalculate and HAVE changes (via Driver)
				listChanged = false;
				context.model.driver.set_DateCreated(new Date("1/2/2009"));
				ok(listChanged, "list should change b/c the driver's created date changed");
				same(getAllowedSalesPersons.apply(context.model.driver), list, "calculated property should have the correct values in it");
			});

			setupTest("list-property-default-values", { description: "list property default values should not be modified", expect: 1 }, function() {
				var o1 = new CarOwner();
				o1.get_InactiveDrivers().add(context.model.driver);

				var o2 = new CarOwner();
				equals(o2.get_InactiveDrivers().length, 0, "Inactive drivers for a new owner should be empty.");
			});

			setupTest("inheritance", { description: "inheritance", expect: 1 }, function() {
				ok(context.model.driver.get_Age, "Driver should have age property via Person");
			});

			context.ready(function() {
				// define the calculated property					
				Driver.$AllowedSalesPersons.calculated({
					fn: getAllowedSalesPersons,
					basedOn: ["this.DateCreated" /*, "this.Employee.HireDate"*/]
				});
				if (Driver.$AllowedSalesPersons._readySignal) {
					Driver.$AllowedSalesPersons._readySignal.waitForAll(function() {
						executeTest("list-property");
					});
				}
				else {
					executeTest("list-property");
				}

				// define a calculated property based on a list
				CarOwner.meta.addProperty({ name: "InactiveDrivers", type: Driver, isList: true });
				executeTest("list-property-default-values");

				// define a calculated property on a base type					
				var ageProp = Person.meta.addProperty({ name: "Age", type: Number }).calculated({
					fn: function calculateAge() {
						var now = new Date();

						// approximation
						return Math.floor(now.subtract(this.get_BirthDate()).days / 365);
					},
					basedOn: ["this.BirthDate"]
				});
				if (ageProp._readySignal) {
					ageProp._readySignal.waitForAll(function() {
						executeTest("inheritance");
					});
				}
				else {
					executeTest("inheritance");
				}
			});
		</script>
	</head>
	<body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView" xmlns:content="javascript:ExoWeb.UI.Content"
		xmlns:template="javascript:ExoWeb.UI.Template" sys:activate="*">
		
		<!-- QUnit Display -->
		<h1 id="qunit-header">Test Results:</h1>
		<h2 id="qunit-banner"></h2>
		<h2 id="qunit-userAgent"></h2>
		<ol id="qunit-tests"></ol>
	</body>
</html>
